package com.atguigu.gmall.rabbit.service;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.rabbit.entity.GmallCorrelationData;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.UUID;

/**
 * @Author: 李旭
 * @Time: 9:38
 * @Description: 统一发送MQ  封装后的实现类
 */
@SuppressWarnings("all")
@Component
public class RabbitService {


    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedisTemplate redisTemplate;

    //发送普通消息
    public boolean sendMessage(String exchange, String routingKey, Object msg) {
        GmallCorrelationData correlationData = retryMessageData(exchange, routingKey, msg);
        //正确的
        rabbitTemplate.convertAndSend(exchange, routingKey, msg, correlationData);
        return true;
    }
    //发送死信延迟消息
    public void sendDeadLetterMessage(String exchange, String routingKey,
                                         Object msg,int delayTime) {
        GmallCorrelationData correlationData = retryMessageData(exchange, routingKey, msg);
        //是延迟消息
        correlationData.setDelay(true);
        //延迟的时间
        correlationData.setDelayTime(delayTime);
        //延迟消息
        rabbitTemplate.convertAndSend(exchange,routingKey,msg,message -> {
            //设置过期时间  基于死信
            System.out.println("发送消息的时间：" + new Date());
            message.getMessageProperties().
                    setExpiration(String.valueOf(delayTime*1000));//TTL  字符串类型 单位是毫秒
            return message;
        },correlationData);
    }

    //发延迟消息 （基于插件的）
    public void sendDelayMessage(String exchange, String routingKey,
                                      Object msg,int delayTime) {
        //基本属性设置
        GmallCorrelationData correlationData = retryMessageData(exchange, routingKey, msg);
        //是延迟消息
        correlationData.setDelay(true);
        //延迟的时间
        correlationData.setDelayTime(delayTime);
        //延迟消息
        rabbitTemplate.convertAndSend(exchange,routingKey,msg,message -> {
            //设置延迟时  基于插件
            System.out.println("发送消息的时间：" + new Date());
            message.getMessageProperties().setDelay(delayTime*1000);
            return message;
        },correlationData);
    }


    private GmallCorrelationData retryMessageData(String exchange, String routingKey, Object msg) {
        //重新发送时的应答对象  保存交换机 RoutingKey Msg
        GmallCorrelationData correlationData = new GmallCorrelationData();
        String uuid = UUID.randomUUID().toString();
        System.out.println("uuid:" + uuid);
        correlationData.setId(uuid);
        correlationData.setExchange(exchange);
        correlationData.setRoutingKey(routingKey);
        correlationData.setMessage(msg);

        //队列应答 不能接收到 GmallCorrelationData  利用Redis保存GmallCorrelationData
        redisTemplate.opsForHash().put("rabbit_prefix", uuid,
                JSONObject.toJSONString(correlationData));
        return correlationData;
    }
}
